package com.zd.commodity.dao.impl;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.math.BigInteger;
import java.util.List;
import java.util.Map;

import org.hibernate.HibernateException;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;
import org.hibernate.transform.Transformers;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

/**
 * 数据访问类
 * @author Administrator
 *
 */
public abstract class BaseDao<T> extends HibernateDaoSupport  {
	
	private Class<T> entityClass;
	
	public BaseDao()
	{
		Type genType = getClass().getGenericSuperclass();   
		Type[] params = ((ParameterizedType) genType).getActualTypeArguments();   
		entityClass =  (Class)params[0]; 
	}
	
	public long getPagedListCountBySql(String sql, Map<String, String> argMap){
		Session session = null;
	    try
	    {
	      session = getHibernateTemplate().getSessionFactory().getCurrentSession();
	      //sql = getSql(sql);
	      sql = argMap==null?getSql(sql):getSql(sql,argMap);
	      System.out.println(sql);
	      SQLQuery query = session.createSQLQuery(sql);
	
	      BigInteger bi = (BigInteger) query.uniqueResult();
	      return bi.longValue();
	    }
	    catch (HibernateException e)
	    {
	      e.printStackTrace();
	      throw e;
	    }
	}
	
	public List getPagedListBySql(Class clasz,String sql, Map<String, String> argMap, int firstResult, int maxResults)
	  {
	    Session session = null;
	    try
	    {
	      session = getHibernateTemplate().getSessionFactory().getCurrentSession();
	      sql = argMap==null?getSql(sql):getSql(sql,argMap);
	      SQLQuery query = session.createSQLQuery(sql);
	      if(firstResult!=-1&&maxResults!=-1){
	    	  query.setFirstResult(firstResult);
	    	  query.setMaxResults(maxResults);
	      }
	      List list = query.list();
	      //query.addEntity(clasz);
	      query.setResultTransformer(Transformers.aliasToBean(clasz));
	      return query.list();
	    }
	    catch (HibernateException e)
	    {
	      e.printStackTrace();
	      throw e;
	    }
	  }
	  public int executeSql(String sql)
	  {
	    Session session = null;
	    SQLQuery sqlQuery = null;
	    try
	    {
	      session = getHibernateTemplate().getSessionFactory().getCurrentSession();
	      sqlQuery = session.createSQLQuery(sql);
	      int i = sqlQuery.executeUpdate();
	      return i;
	    }
	    catch (HibernateException e)
	    {
	      e.printStackTrace();
	      throw e;
	    }
	  }
	
	 public int executeSql(String sql, Map<String, String> argMap)
	  {
	    if (argMap != null)
	    {
	      sql = getSql(sql, argMap);
	    }
	    else
	    {
	      sql = getSql(sql);
	    }
	    Session session = null;
	    SQLQuery sqlQuery = null;
	    try
	    {
	      session = getHibernateTemplate().getSessionFactory().getCurrentSession();
	      sqlQuery = session.createSQLQuery(sql);
	      int i = sqlQuery.executeUpdate();
	      return i;
	    }
	    catch (HibernateException e)
	    {
	      e.printStackTrace();
	      throw e;
	    }
	  }
	 
	 public String getSql(String sqlName)
	  {
		 
	    String sql = SqlManager.getSqlText(getClass(), sqlName);
	    
	    if (sql == null)
	    {
	      return sqlName;
	    }

	    return sql;
	  }
	  public String getSql(String sqlName, Map<String, String> valMap)
	  {
		  String sql = getSql(sqlName);

	    String sqlExpB = "[";
	    String sqlExpE = "]";

	    String argExpB = "{:";
	    String argExpE = ":}";

	    if (sql != null)
	    {
	    while (sql.indexOf("]") != -1)
	      {
	    	  
	        String tmp = sql.substring(sql.indexOf("[") + 1, sql
	          .indexOf("]"));

	        
	        String replacStr = replacWithMap(tmp, "{:", ":}", valMap);
	        sql = sql.substring(0, sql.indexOf("[")) + replacStr + 
	          sql.substring(sql.indexOf("]") + 1);

	        if (sql.indexOf("[") == -1) break; 
	      };

	      while ((sql.indexOf("{:") != -1) && (sql.indexOf(":}") != -1))
	      {
	        String argName = sql.substring(sql.indexOf("{:") + "{:".length(), sql
	          .indexOf(":}"));
	        sql = sql.substring(0, sql.indexOf("{:")) + (
	          valMap.get(argName) == null ? "" : (String)valMap.get(argName)) + 
	          sql.substring(sql.indexOf(":}") + ":}".length());
	      }

	    }

	    return sql;
	  }
	  
	  private String replacWithMap(String sql, String argExpB, String argExpE, Map<String, String> argMap)
	  {
	    if (argMap == null)
	    {
	      return "";
	    }
	    if (sql != null)
	    {
	      if ((sql.indexOf(argExpB) != -1) && (sql.indexOf(argExpE) != -1))
	      {
	        String argName = sql.substring(sql.indexOf(argExpB) + argExpB.length(), sql
	          .indexOf(argExpE));

	        if ((argMap.get(argName) != null) && 
	          (!"".equals(argMap.get(argName))))
	        {
	          sql = " " + sql.substring(0, sql.indexOf(argExpB)) + 
	            (String)argMap.get(argName) + 
	            sql.substring(sql.indexOf(argExpE) + argExpE.length()) + " ";
	        }
	        else
	        {
	          sql = "";
	        }
	      }
	    }
	    return sql;
	  }
	
	
	public List<T> getList(T t1,T t2,Object param) {
		
		DetachedCriteria dc = getDetachedCriteria(t1, t2, param);
		return getHibernateTemplate().findByCriteria(dc);
	}
	
	/**
	 * 分页
	 * @param t1
	 * @param firstResult
	 * @param maxResults
	 * @return
	 */
	public List<T> getListByPage(T t1,T t2,Object param,int firstResult,int maxResults) {
		
			
		DetachedCriteria dc = getDetachedCriteria(t1, t2, param)	;
		return getHibernateTemplate().findByCriteria(dc, firstResult, maxResults);
	}

	/**
	 * 统计记录数
	 * @param t1
	 * @param firstResult
	 * @param maxResults
	 * @return
	 */
	public long getCount(T t1,T t2,Object param) {
		
		DetachedCriteria dc = getDetachedCriteria(t1, t2, param)	;
		dc.setProjection(Projections.rowCount());		
		List<Long> list= getHibernateTemplate().findByCriteria(dc);
		return list.get(0);
	}

	/**
	 * 构建查询条件
	 * @param t1
	 * @param t2
	 * @param param
	 * @return
	 */
	public abstract DetachedCriteria getDetachedCriteria(T t1,T t2,Object param);
	

	/**
	 * 增加
	 */
	public void add(T t) {		
		getHibernateTemplate().save(t);		
	}
	
	/**
	 * 删除
	 * @param id
	 */
	public void delete(Long id)
	{
		T t =  getHibernateTemplate().get(entityClass, id);
		getHibernateTemplate().delete(t);
	}

	/**
	 * 获取实体
	 */
	public T get(Long id) {
		return getHibernateTemplate().get(entityClass, id);
	}

	/**
	 * 更新
	 */
	public void update(T t) {

		getHibernateTemplate().update(t);
	}
	public List getListBySql(String sql, Map<String, String> argMap)
	{
		Session session = null;
		try
		{
			session = getHibernateTemplate().getSessionFactory().getCurrentSession();
			sql = argMap==null?getSql(sql):getSql(sql,argMap);
			SQLQuery query = session.createSQLQuery(sql);
			return query.list();
		}
		catch (HibernateException e)
		{
			e.printStackTrace();
			throw e;
		}
	}
	
}
